package com.zhongyouyun.other.file.factory;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.setting.dialect.Props;
import cn.hutool.setting.dialect.PropsUtil;
import com.zhongyouyun.admin.controller.FileController;
import com.zhongyouyun.admin.model.FileModel;
import com.zhongyouyun.other.exception.BizException;
import com.zhongyouyun.other.file.Bean.FileBean;
import com.zhongyouyun.other.file.Bean.FileBeanWork;
import com.zhongyouyun.other.file.abstractfactory.FileFactory;
import com.zhongyouyun.other.model.Result;
import com.zhongyouyun.utils.FileUtils;
import com.zhongyouyun.utils.PropUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class LocalFileFactory extends FileFactory {
    private final static Logger logger = LoggerFactory.getLogger(LocalFileFactory.class);


    /*
       判断是否是
     */
    private String saveFile(MultipartFile file) {
        String saveStr = "";
        try {
            BufferedImage image = null;
            image = ImageIO.read(file.getInputStream());
            if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {

                System.out.println("-----------------------------------------------------------------------");
                saveStr += "/file";
            } else {
                saveStr += "/image";
            }
        } catch (Exception e) {

            e.printStackTrace();

        }

        return saveStr;
    }

    @Override
    public FileBean uploadFile(MultipartFile file) {

        FileBean fileBean = new FileBean();
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("file.localUrl");


        try {
            if (file.isEmpty()) {
                fileBean.setState(1);
                fileBean.setMessage("上传文件不能为空");
                return fileBean;
            }
            filePath += saveFile(file);
            String date = DateUtil.today();
            date = date.replaceAll("-", "");
            // 获取文件名

            String originalNameUrl = file.getOriginalFilename();
            String[] originalNames = originalNameUrl.split("\\.");//文件名
            String fileName = RandomUtil.randomString(18);
            System.out.println(RandomUtil.randomString(18));
            logger.info("上传的文件名为：" + originalNameUrl);//写日志
            // 获取文件的后缀名
            String suffixName = originalNameUrl.substring(originalNameUrl.lastIndexOf("."));
            // String suffixName = originalNameUrl.substring(originalNameUrl.lastIndexOf("."));

            // 设置文件存储路径         *************************************************
            String path = filePath + "/" + date + "/" + fileName + suffixName;
            File dest = new File(new File(path).getAbsolutePath());// dist为文件，有多级目录的文件

            // 检测是否存在目录
            if (!dest.getParentFile().exists()) {//因此这里使用.getParentFile()，目的就是取文件前面目录的路径
                dest.getParentFile().mkdirs();// 新建文件夹
            }
            file.transferTo(dest);// 文件写入
            String fileMd5 = FileUtils.getStringMd5(new File(path));
            fileBean.setFileMd5(fileMd5);
            fileBean.setState(0);
            fileBean.setExtensionName(suffixName);
            fileBean.setFileName(fileName);
            fileBean.setOriginalName(originalNames[0]);
            fileBean.setUrl(date);
            fileBean.setHttpURL("/image/" + date + "/" + fileName + suffixName);
        } catch (Exception e) {
            fileBean.setState(1);
            fileBean.setMessage("上传文件报错:" + e.getMessage());
            e.printStackTrace();
        }
        return fileBean;
    }

    @Override
    public void downloadFile(FileModel fileModel, HttpServletRequest request, HttpServletResponse response) {
        FileBeanWork fileBeanWork = new FileBeanWork();

        FileBean fileBean = new FileBean();
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("file.localUrl");
        try {

            request.setCharacterEncoding("utf-8");
            // 文件存储路径


            // 从请求中获取文件名
            String fileName = fileModel.getOriginalName() + fileModel.getExtensionName();

            // 创建输出流对象
            ServletOutputStream outputStream = response.getOutputStream();


            //以字节数组的形式读取文件
            byte[] bytes = FileUtil.getAbsolutePath(filePath + "/" + fileModel.getUrl() + "/" + fileModel.getFileName() + fileModel.getExtensionName()).getBytes();

            // 设置返回内容格式
            response.setContentType("application/octet-stream");

            // 把文件名按UTF-8取出并按ISO8859-1编码，保证弹出窗口中的文件名中文不乱码
            // 中文不要太多，最多支持17个中文，因为header有150个字节限制。
            // 这一步一定要在读取文件之后进行，否则文件名会乱码，找不到文件
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");

            // 设置下载弹窗的文件名和格式（文件名要包括名字和文件格式）
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

            // 返回数据到输出流对象中
            outputStream.write(bytes);
            // 关闭流对象
            IoUtil.close(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public FileBeanWork uploadhandleFile(List<MultipartFile> files) {

        FileBeanWork fileBeanWork = new FileBeanWork();
        List<FileBean> list = new ArrayList<FileBean>();
        MultipartFile file = null;
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("file.localUrl");
        BufferedOutputStream stream = null;
        String date = DateUtil.today();
        date = date.replaceAll("-", "");
        for (int i = 0; i < files.size(); ++i) {
//            BufferedImage image = null;
//            image = ImageIO.read(file.getInputStream());
//            if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
//                filePath+="/file";
//            }else{
//                filePath+="/image";
//            }
            file = files.get(i);
            File dest = new File(filePath + saveFile(file) + "/" + date);
            // 检测是否存在目录
            if (!dest.exists()) {
                dest.mkdirs();// 新建文件夹
            }
            if (!file.isEmpty()) {
                try {
                    byte[] bytes = file.getBytes();
                    String originalNameUrl = file.getOriginalFilename();
                    String[] originalNames = originalNameUrl.split("\\.");//文件名
                    String fileName = RandomUtil.randomString(18);
                    String suffixName = originalNameUrl.substring(originalNameUrl.lastIndexOf("."));
                    stream = new BufferedOutputStream(new FileOutputStream(
                            new File(filePath + saveFile(file) + "/" + date + "/" + fileName + suffixName)));//设置文件路径及名字
                    stream.write(bytes);// 写入
                    stream.close();
                    fileBeanWork.setState(0);
                    String fileMd5 = FileUtils.getStringMd5(new File(filePath + saveFile(file) + "/" + date + "/" + fileName + suffixName));
                    FileBean fileBean = new FileBean();
                    fileBean.setFileMd5(fileMd5);
                    fileBean.setExtensionName(suffixName);
                    fileBean.setUrl(date);
                    fileBean.setFileName(fileName);
                    fileBean.setOriginalName(originalNames[0]);
                    list.add(fileBean);
                    fileBeanWork.setMessage("上传成功");
                } catch (Exception e) {
                    stream = null;
                    fileBeanWork.setState(1);
                    fileBeanWork.setMessage("第 " + i + " 个文件上传失败 ");
                    return fileBeanWork;
                    //return "第 " + i + " 个文件上传失败 ==> " + e.getMessage();
                }
            } else {
                fileBeanWork.setState(1);
                fileBeanWork.setMessage("第 " + i + " 个文件上传失败因为文件为空");
                return fileBeanWork;
            }
        }
        fileBeanWork.setList(list);
        return fileBeanWork;
    }

    @Override
    public FileBeanWork delFile(FileModel fileModel) {
        FileBeanWork fileBeanWork = new FileBeanWork();
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("file.localUrl");
        filePath = filePath + "/" + fileModel.getUrl() + "/" + fileModel.getFileName() + fileModel.getExtensionName();
        Boolean flag = FileUtil.del(filePath);
        if (flag) {
            fileBeanWork.setState(0);
            fileBeanWork.setMessage("删除成功");
            return fileBeanWork;
        }
        fileBeanWork.setState(1);
        fileBeanWork.setMessage("删除失败");
        return fileBeanWork;
    }

    @Override
    public String uploadHtml(String html) {
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("html.localUrl");
        //设置日期
        String date = DateUtil.today();
        date = date.replaceAll("-", "");
        String path = filePath + "/" + date;
        File fileDoc = new File(path);
        //如果文件夹不存在
        if (!fileDoc.exists()) {
            //创建文件夹
            fileDoc.mkdirs();
        }
        String htmlAbsolutePath = fileDoc.getAbsolutePath();
        String fileName = RandomUtil.randomString(18);
        File outFile = new File(htmlAbsolutePath + "/" + fileName + ".html");
        System.out.println(htmlAbsolutePath + "/" + fileName + ".html");
        BufferedWriter output = null;
        try {
            output = new BufferedWriter(new FileWriter(outFile));
            output.write(html);
        } catch (
                IOException e) {
            e.printStackTrace();
        } finally {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "html/" + date + "/" + fileName + ".html";
    }

    @Transactional
    public Boolean deleteHtml(List<String> urlList) {
        Boolean flag = false;
        long i = 0L;
        Props props = PropUtils.get("properties/file");
        String filePath = props.getStr("html.localUrl");
        i += urlList.stream().map(s -> FileUtil.del(filePath+"\\"+(urlList.get(0).replaceAll("/apiupload","").replaceAll("/","\\")))).filter(fl -> fl).count();
        if (i == urlList.size()) {
            flag = true;
        } else {
            throw new BizException(1, "删除文件错误错误", false);
        }
        return flag;
    }
}
